//! Option 枚举示例
//! `Option<T>` 枚举用于处理可能缺失的值，它有两个变体：
//! - Some(T): 包含一个值
//! - None: 表示没有值

/// Option 基础用法
#[test]
pub fn option_basics() {
    // 创建 Some 和 None 值
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number: Option<i32> = None;

    println!("Option 基础示例:");
    println!("some_number: {some_number:?}");
    println!("some_string: {some_string:?}");
    println!("absent_number: {absent_number:?}");
}

/// 使用 match 处理 Option
#[test]
pub fn matching_option() {
    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {
            None => None,
            Some(i) => Some(i + 1),
        }
    }

    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);

    println!("匹配 Option 示例:");
    println!("5 + 1 = {six:?}");
    println!("None + 1 = {none:?}");
}

/// 使用 if let 简化 Option 处理
#[test]
pub fn if_let_option() {
    let some_u8_value = Some(0u8);

    // 使用 match
    match some_u8_value {
        Some(3) => println!("匹配到了三"),
        _ => (), // 忽略其他所有情况
    }

    // 使用 if let 简化代码
    if let Some(3) = some_u8_value {
        println!("匹配到了三");
    }

    // if let 也可以包含 else
    let another_u8_value = Some(5u8);
    if let Some(3) = another_u8_value {
        println!("匹配到了三");
    } else {
        println!("没有匹配到三");
    }
}

/// Option 的常用方法
#[test]
pub fn option_methods() {
    let some_value: Option<i32> = Some(10);
    let none_value: Option<i32> = None;

    // 使用 is_some 和 is_none 方法
    println!("Option 方法示例:");
    println!("some_value is some: {}", some_value.is_some());
    println!("some_value is none: {}", some_value.is_none());
    println!("none_value is some: {}", none_value.is_some());
    println!("none_value is none: {}", none_value.is_none());

    // 使用 unwrap 和 expect
    println!("使用 unwrap: {}", some_value.unwrap());
    println!("使用 expect: {}", some_value.expect("值不存在"));

    // 使用 unwrap_or 提供默认值
    println!("使用 unwrap_or: {}", none_value.unwrap_or(0));

    // 使用 map 转换值
    let mapped = some_value.map(|x| x * 2);
    println!("使用 map: {:?}", mapped);

    // 使用 and_then 链式处理
    let chained = some_value.and_then(|x| Some(x + 5));
    println!("使用 and_then: {:?}", chained);
}
